import subprocess
import time
import json
import sys
import os
from urllib.parse import urlparse
from datetime import datetime
import argparse

git_token = ""
github_token = ""

critical = 0
medium = 0
low = 0

def log_to_file(filename,text):
    with open(filename,"a") as f:
        f.write(text)
        f.write("\n")
    return

def file_from_url(url):
    a = urlparse(url)
    #print(a.path)                    
    filenamext = os.path.basename(a.path)
    filename = os.path.splitext(filenamext)[0]
    return filename

def rm_files(dirname):
    zipfile = str(dirname)+".zip"
    cmd = "rm -rf "+dirname
    cmdout = subprocess.Popen(cmd,stdout=subprocess.PIPE,shell=True).communicate()[0]
    cmd2 = "rm "+zipfile
    cmdout2 = subprocess.Popen(cmd2,stdout=subprocess.PIPE,shell=True).communicate()[0]
    return 
        
def clone_github_repo(repo,token):
    #cmd = "git clone https://gitlab-ci-token:"+token+"@"+repo
    cmd = "git clone https://x-access-token:"+token+"@"+repo
    cmdout = subprocess.Popen(cmd,stdout=subprocess.PIPE,shell=True).communicate()[0]
    return
        
def clone_repo(repo,token):
    cmd = "git clone https://gitlab-ci-token:"+token+"@"+repo
    cmdout = subprocess.Popen(cmd,stdout=subprocess.PIPE,shell=True).communicate()[0]
    return

def zip_dir(dirname):
    zipfile = str(dirname)+".zip"
    cmd = "zip -r "+zipfile+" "+dirname
    cmdout = subprocess.Popen(cmd,stdout=subprocess.PIPE,shell=True).communicate()[0]
    return zipfile

def get_token():
    cmdout = subprocess.Popen(["curl -s -X POST 'http://solar.lan/app/api/v1/auth/jwt' -H 'accept: application/json' -H 'Content-Type: application/x-www-form-urlencoded' -d 'username=&password=' -v"],stdout=subprocess.PIPE,shell=True).communicate()[0]
    request=json.loads(cmdout.decode('UTF-8'))
    token = request["accessToken"]
    print(token)
    return token
    
def upload_file(token,fname):
    now = datetime.now()
    date_time=now.strftime("%d%m%Y")
    project_name = os.path.basename(fname)+"_"+date_time
    cmd = "curl -s -X POST 'http://solar.lan/app/api/v1/scan/start' -H 'accept: application/json' -H 'Authorization: Bearer "+token+"' -H 'Content-Type: multipart/form-data' -F 'excludeDirs=' -F 'branch=' -F 'ruleSet=' -F 'checkboxNoBuild=' -F 'name="+project_name+"' -F 'repoPassword=' -F 'saveRepoCredentials=' -F 'sourceEncoding=' -F 'checkboxUseUserPatterns=' -F 'visualStudio=' -F 'checkboxAnalyzeLibs=' -F 'repoLogin=' -F 'incremental=' -F 'link=' -F 'languages=' -F 'uuid=' -F 'file=@"+fname+"' -F 'nameEncoding='"
    #print(cmd)
    cmdout = subprocess.Popen(cmd,stdout=subprocess.PIPE,shell=True).communicate()[0]
    request = cmdout.decode('UTF-8')
    return request

def get_scan_status(token,scan_uuid):
    global critical
    global medium
    global low
    cmd = "curl -s -X GET 'http://solar.lan/app/api/v1/scans/"+scan_uuid+"/compact' -H 'accept: application/json' -H 'Authorization: Bearer "+token+"'"
    print(cmd)
    cmdout = subprocess.Popen(cmd,stdout=subprocess.PIPE,shell=True).communicate()[0]
    #print(cmdout.decode('UTF-8'))
    request=json.loads(cmdout.decode('UTF-8'))
    status = request["progress"]
    print("Critical :"+str(request["critical"]))
    critical= str(request["critical"])
    log_to_file("debug.log","Critical :"+critical)
    print("Medium :"+str(request["medium"]))
    medium = str(request["medium"])
    log_to_file("debug.log","Medium :"+medium)
    print("Low :"+str(request["low"]))
    low = str(request["low"])
    log_to_file("debug.log","Low :"+low)
    return status
    
def download_report(token,project_uuid,scan_uid,report_name):
    cmd = "curl -s -X POST 'http://solar.lan/app/api/v1/report/pdf' -H 'accept: application/octet-stream' -H 'Content-Type: application/json' -H 'Authorization: Bearer "+token+"' -d '{\"projectUuid\":\""+project_uuid+"\",\"scanUuids\":[\""+scan_uid+"\"],\"exportSettings\":{\"uuid\":\"system_template_settings_uuid\",\"projectInfoSettings\":{\"securityLevelDynamics\":true,\"vulnNumberDynamics\":true,\"scanHistory\":0},\"sort\":\"CR\",\"scanInfoSettings\":{\"included\":true,\"foundVulnChart\":true,\"typeVulnChart\":true,\"langStats\":true,\"scanErrorInfo\":true,\"scanSettings\":true},\"filterSettings\":{\"critical\":true,\"medium\":true,\"low\":false,\"info\":false,\"standardLibs\":true,\"classFiles\":true,\"waf\":true,\"jira\":true,\"fuzzy\":{\"included\":false,\"critical\":4,\"medium\":4,\"low\":4,\"info\":4,\"percentile\":10,\"mode\":\"TRUE\"},\"lang\":\"ABAP,ANDROID,APEX,CS,CCPP,COBOL,CONFIG,DELPHI,GO,GROOVY,HTML5,JAVA,JAVASCRIPT,KOTLIN,LOTUS,OBJC,PASCAL,PHP,PLSQL,PYTHON,PERL,RUBY,RUST,SCALA,SOLIDITY,SWIFT,TSQL,TYPESCRIPT,VBNET,VBA,VBSCRIPT,VB,VYPER,ONES\"},\"tableSettings\":{\"included\":true,\"entriesSettings\":{\"notProcessed\":true,\"confirmed\":true,\"rejected\":false},\"entryNum\":0},\"detailedResultsSettings\":{\"included\":true,\"entriesSettings\":{\"notProcessed\":true,\"confirmed\":true,\"rejected\":false},\"entryNum\":0,\"comment\":true,\"jiraInfo\":true,\"traceNum\":1,\"sourceCodeNum\":3},\"wafSettings\":{\"included\":true,\"entriesSettings\":{\"notProcessed\":true,\"confirmed\":true,\"rejected\":false},\"imperva\":true,\"mod\":true,\"f5\":true},\"generalSettings\":{\"reportSettings\":true,\"contents\":true,\"locale\":\"ru\"}},\"comparisonSettings\":{\"included\":false,\"scanUuid\":null,\"newIssue\":true,\"saved\":true,\"fixed\":false,\"entryNum\":0,\"scanSettings\":true}}' --output ./reports/"+report_name+".pdf"
    print(cmd)
    cmdout = subprocess.Popen(cmd,stdout=subprocess.PIPE,shell=True).communicate()[0]
    
    
parser = argparse.ArgumentParser()
parser.add_argument('-f',dest='arg_filename',action='append',help="locale file scan")
parser.add_argument('-gl',dest='arg_repo',action='append',help="git repo scan")
parser.add_argument('-gh',dest='arg_repo_github',action='append',help="github repo scan")

args = parser.parse_args()

if args.arg_filename:
    fname = args.arg_filename[0]
    log_to_file("debug.log",fname)
    print("Scanning file..."+fname)
    token = get_token()
    print("Token: "+token)
    solar_response = upload_file(token,fname)
    log_to_file("debug.log",solar_response)
    print("Upload result: "+ solar_response)

if args.arg_repo:
    repo_str = args.arg_repo[0]
    print("Scanning repo..."+repo_str)
    clone_repo(repo_str,git_token)
    zipfile= zip_dir(file_from_url(repo_str))    
    token = get_token()
    solar_response = upload_file(token,zipfile)
    log_to_file("debug.log",solar_response)
    rm_files(file_from_url(repo_str))
    print("Upload result: "+ solar_response)
    
# github
if args.arg_repo_github:
    repo_str = args.arg_repo_github[0]
    print("Scanning repo..."+repo_str)
    clone_github_repo(repo_str,github_token)
    zipfile= zip_dir(file_from_url(repo_str))    
    token = get_token()
    solar_response = upload_file(token,zipfile)
    log_to_file("debug.log",solar_response)
    rm_files(file_from_url(repo_str))
    print("Upload result: "+ solar_response)   
 
    
json_uuids = json.loads(solar_response)

project_uuid = json_uuids["projUuid"]
scan_uuid =  json_uuids["scanUuid"]   
    

print("Project UUID "+ project_uuid)
print("Scan UUID "+ scan_uuid)

minutes = 0

while 1:
    token = get_token()
    progress = get_scan_status(token,scan_uuid)
    if int(progress) == 100:
        break
    print("Progress: " + progress)
    log_to_file("debug.log","Progress: " + progress)
    time.sleep(60)
    minutes = minutes + 1
    print("Scantime (minutes): "+str(minutes))
    log_to_file("debug.log","Scantime (minutes): " + str(minutes))
    
now = datetime.now()
date_time=now.strftime("%d%m%Y")    

if args.arg_repo:
    project_name = repo_str
    report_name = file_from_url(repo_str)+"_"+date_time 

if args.arg_repo_github:
    project_name = repo_str
    report_name = file_from_url(repo_str)+"_"+date_time      

if args.arg_filename:
    project_name = fname
    report_name = fname+"_"+date_time

report_name = report_name.replace(" ","_")
report_name = report_name.replace("/","_")
download_report(token,project_uuid,scan_uuid,report_name)

log = str(project_name)+","+str(report_name)+","+str(date_time)+","+str(now.year)+","+str(now.month)+","+str(now.day)+","+str(project_uuid)+","+str(scan_uuid)+","+str(critical)+","+str(medium)+","+str(low)+","+str(minutes)
log_to_file("result.log",str(log))
